﻿#pragma once
#include <iostream>

using namespace std;

enum TEACHER_SEX_E{
	TEACHER_SEX_FEMALE,
#define TEACHER_SEX_FEMALE_STR "女"
	TEACHER_SEX_MAMLE
#define TEACHER_SEX_MALE_STR "男"
};

enum TEACHER_GRADE_E{
	TEACHER_GRADE_A,
#define TEACHER_GRADE_A_STR "教授"
	TEACHER_GRADE_B,
#define TEACHER_GRADE_B_STR "高级教师"
	TEACHER_GRADE_C,
#define TEACHER_GRADE_C_STR "中级教师"
	TEACHER_GRADE_D
#define TEACHER_GRADE_D_STR "初级教师"
};

enum TEACHER_TYPE_E{
	TEACHER_TYPE_NULL,
	TEACHER_TYPE_PE,
#define TEACHER_TYPE_PE_STR "体育"
	TEACHER_TYPE_CHINESE,
#define TEACHER_TYPE_CHINESE_STR "语文"
	TEACHER_TYPE_MATH,
#define TEACHER_TYPE_MATH_STR "数学"
	TEACHER_TYPE_ENGLISH,
#define TEACHER_TYPE_ENGLISH_STR "英语"
	TEACHER_TYPE_PHYSICS,
#define TEACHER_TYPE_PHYSICS_STR "物理"
	TEACHER_TYPE_CHEMISTRY,
#define TEACHER_TYPE_CHEMISTRY_STR "化学"
	TEACHER_TYPE_BIOLOGY,
#define TEACHER_TYPE_BIOLOGY_STR "生物"
	
};
static char* GET_TEACHER_TYPE_STR(TEACHER_TYPE_E e)
{
	switch(e)
	{
	case TEACHER_TYPE_PE:
		 {
			 return TEACHER_TYPE_PE_STR;
		 }break;
	case TEACHER_TYPE_CHINESE:
		 {
			 return TEACHER_TYPE_CHINESE_STR;
		 }break;
	case TEACHER_TYPE_MATH:
		 {
			 return TEACHER_TYPE_MATH_STR;
		 }break;
	case TEACHER_TYPE_ENGLISH:
		 {
			 return TEACHER_TYPE_ENGLISH_STR;
		 }break;
	case TEACHER_TYPE_PHYSICS:
		 {
			 return TEACHER_TYPE_PHYSICS_STR;
		 }break;
	case TEACHER_TYPE_CHEMISTRY:
		 {
			 return TEACHER_TYPE_CHEMISTRY_STR;
		 }break;

	case TEACHER_TYPE_NULL:
	default:
		 {
			 return NULL;
		 }break;
	};
}

class Teacher01
{
public:
	Teacher01(int age, char* name, TEACHER_SEX_E sex);
	Teacher01(int age, char* name, TEACHER_SEX_E sex, int salary, TEACHER_GRADE_E grade);
	Teacher01(const Teacher01& t);

	~Teacher01();

public:
	//降薪
	void payCut(int a);

	//加薪
	void payRaise(int a);

	//升职
	void upGraded();

	//降职
	void downGraded();

	//授课（可被重写）
	virtual void lecture();
	
	//其他信息（可被重写）
	virtual void otherInfo();
	
	void printT()
	{
		cout <<"teacher: "<<name<<", "<<age<<", "<<sex<<endl;
	}

	//右移号重载
	friend ostream & operator<< (ostream &out, Teacher01 &t);

	//等号重载
	Teacher01& operator=(const Teacher01& t);
		//Teacher01& operator=(const Teacher01& t);
	//大于号重载
	bool operator>(const Teacher01& t);

	//小于号重载
	bool operator<(const Teacher01& t);

	//双等号重载
	bool operator==(const Teacher01& t);

	//不等号重载
	bool operator!=(const Teacher01& t);

public:
	int salary;
	TEACHER_GRADE_E grade;

public:
	int get_age(){ return this->age; }
	void set_age(int age){ this->age = age; }

	char* get_name(){ return this->name; }
	void set_name(char* name){ sprintf(this->name, name); }

	TEACHER_SEX_E get_sex(){ return this->sex; }
	void set_sex(TEACHER_SEX_E sex){ this->sex = sex; }

	TEACHER_TYPE_E get_type(){return this->type;}
	void set_type(TEACHER_TYPE_E type){this->type = type;}
private:
	int age;
	char name[128];
	TEACHER_SEX_E sex;
	TEACHER_TYPE_E type;
};

Teacher01::Teacher01(int age, char* name, TEACHER_SEX_E sex)
{
	this->age = age;
	sprintf(this->name, name);
	this->sex = sex;
	this->salary = 20000;
	this->grade = TEACHER_GRADE_D;
}

Teacher01::Teacher01(int age, char* name, TEACHER_SEX_E sex, int salary, TEACHER_GRADE_E grade)
{
	this->age = age;
	sprintf(this->name, name);
	this->sex = sex;
	this->salary = salary;
	this->grade = grade;
	this->type = TEACHER_TYPE_NULL;
}

Teacher01::Teacher01(const Teacher01& t)
{
	this->age = t.age;
	sprintf(this->name, t.name);
	this->sex = t.sex;
	this->salary = t.salary;
	this->grade = t.grade;
	this->type = TEACHER_TYPE_NULL;
}

Teacher01::~Teacher01()
{

}


//降薪
void Teacher01::payCut(int a)
{
	this->salary -= a;
	if (this->salary < 0)
	{
		this->salary = 0;
	}
}

//加薪
void Teacher01::payRaise(int a)
{
	this->salary += a;
}

//升职
void Teacher01::upGraded()
{
	if (this->grade > TEACHER_GRADE_A)
	{
		this->grade = (TEACHER_GRADE_E)(((int)this->grade)-1);
	}
}

//降职
void Teacher01::downGraded()
{
	if (this->grade < TEACHER_GRADE_D)
	{
		this->grade = (TEACHER_GRADE_E)(((int)this->grade)+1);
	}
}

//授课（可被重写）
void Teacher01::lecture()
{
	cout<<"上课"<<endl;
}

void Teacher01::otherInfo()
{

}

//等号重载
Teacher01& Teacher01::operator=(const Teacher01& t)
{
	this->age = t.age;
	sprintf(this->name, t.name);
	this->sex = t.sex;
	this->salary = t.salary;
	this->grade = t.grade;
	return *this;
}

//大于号重载
bool Teacher01::operator>(const Teacher01& t)
{
	if (this->grade > t.grade)
	{
		return false;
	}
	return true;
}

//小于号重载
bool Teacher01::operator<(const Teacher01& t)
{
	if (this->grade < t.grade)
	{
		return false;
	}
	return true;
}

//双等号重载
bool Teacher01::operator==(const Teacher01& t)
{
	if (this->grade == t.grade)
	{
		return true;
	}
	return false;
}

//不等号重载
bool Teacher01::operator!=(const Teacher01& t)
{
	return !(*this == t);
}

//右移号重载
ostream & operator<< (ostream &out, Teacher01 &t)
{
	out<<"---------------------------"<<endl;
	out<<"姓名： "<<t.name<<endl;
	out<<"年龄 "<<t.age<<endl;
	out<<"性别 "<<t.sex<<endl;
	out<<"级别 "<<t.grade<<endl;
	out<<"工资 "<<t.salary<<endl;
	if (t.type)
	{
		cout<<"类别 "<<GET_TEACHER_TYPE_STR(t.type)<<endl;
	}
	t.otherInfo();
	out<<"---------------------------"<<endl;
	return out;
}

